/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.api.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.api.config.SpringConfig;
import com.yami.shop.bean.app.dto.UserDto;
import com.yami.shop.bean.app.param.SetUserWxOpenIdParam;
import com.yami.shop.bean.app.param.UserInfoParam;
import com.yami.shop.bean.dto.UserTreeDto;
import com.yami.shop.bean.enums.UserFundDetailEnum;
import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.User;
import com.yami.shop.bean.model.UserFundDetail;
import com.yami.shop.bean.param.OrderParamPublicParam;
import com.yami.shop.bean.param.UpdateMobileParam;
import com.yami.shop.bean.param.UserRegisterParam;
import com.yami.shop.bean.vo.UserFundDetailVo;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.PrincipalUtil;
import com.yami.shop.common.util.RedisUtil;
import com.yami.shop.otherservice.OneLevelDistributionService;
import com.yami.shop.otherservice.SendSmsService;
import com.yami.shop.payment.WeChatPayment;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.security.common.manager.PasswordManager;
import com.yami.shop.service.OrderService;
import com.yami.shop.service.UserFundDetailService;
import com.yami.shop.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jodd.util.StringUtil;
import lombok.AllArgsConstructor;
import cn.hutool.core.bean.BeanUtil;
import com.yami.shop.common.response.ServerResponseEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lanhai
 */
@RestController
@RequestMapping("/p/user")
@Tag(name = "用户接口")
@AllArgsConstructor
public class UserController {

	private final UserService userService;
	private final PasswordEncoder passwordEncoder;
	private final PasswordManager passwordManager;

	@Autowired
	private OrderService orderService;
	@Autowired
	private UserFundDetailService userFundDetailService;

	@Autowired
	private OneLevelDistributionService oneLevelDistributionService;

	@Autowired
	private WeChatPayment weChatPayment;

	public static String updateMobileCode="updateMobileCode:";

	private final SpringConfig springConfig;

	private final SendSmsService sendSmsService;

	/**
	 * 查看用户接口
	 */
	@GetMapping("/userInfo")
	@Operation(summary = "查看用户信息" , description = "根据用户ID（userId）获取用户信息")
	public ServerResponseEntity<UserDto> userInfo() {
		String userId = SecurityUtils.getUser().getUserId();
		User user = userService.getById(userId);

		user.setLoginPassword("");
		user.setPayPassword("");

		UserDto userDto = BeanUtil.copyProperties(user, UserDto.class);

		User byId = userService.getById(user.getSharedUid());
		if (byId != null){
			userDto.setSharedUidMobile(byId.getUserMobile());
		}

		User byId1 = userService.getById(user.getHigherLevelUid());
		if (byId1 != null){
			userDto.setHigherLevelUidMobile(byId1.getUserMobile());
		}

		return ServerResponseEntity.success(userDto);
	}

	@PutMapping("/setUserInfo")
	@Operation(summary = "设置用户信息" , description = "设置用户信息")
	public ServerResponseEntity<Void> setUserInfo(@RequestBody UserInfoParam userInfoParam) {
		String userId = SecurityUtils.getUser().getUserId();
		User user = new User();
		user.setUserId(userId);
		user.setPic(userInfoParam.getAvatarUrl());//头像
		user.setNickName(userInfoParam.getNickName());//昵称
		user.setPersonalizedSignature(userInfoParam.getPersonalizedSignature());//个性签名
		userService.updateById(user);
		return ServerResponseEntity.success();
	}

	@PutMapping("/updatePwd")
	@Operation(summary = "修改密码" , description = "修改密码")
	public ServerResponseEntity<Void> updatePwd(@Valid @RequestBody UserRegisterParam userPwdUpdateParam) {
		if(StringUtil.isBlank(userPwdUpdateParam.getOldLoginPassword())){
			throw new YamiShopBindException("旧密码不能为空");
		}

		String userId = SecurityUtils.getUser().getUserId();
		User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUserId, userId));
		if (user == null) {
			// 无法获取用户信息
			throw new YamiShopBindException("无法获取用户信息");
		}

		//String oldLogin = passwordManager.decryptPassword(userPwdUpdateParam.getOldLoginPassword());

		if(!passwordEncoder.matches(userPwdUpdateParam.getOldLoginPassword(),user.getLoginPassword())){
			throw new YamiShopBindException("旧密码错误");
		}

		String decryptPassword = passwordManager.decryptPassword(userPwdUpdateParam.getPassWord());
		if (StrUtil.isBlank(decryptPassword)) {
			// 新密码不能为空
			throw new YamiShopBindException("新密码不能为空");
		}
		String password = passwordEncoder.encode(decryptPassword);
		if (StrUtil.equals(password, user.getLoginPassword())) {
			// 新密码不能与原密码相同
			throw new YamiShopBindException("新密码不能与原密码相同");
		}
		user.setModifyTime(new Date());
		user.setLoginPassword(password);
		userService.updateById(user);
		return ServerResponseEntity.success();
	}

	@PutMapping("/updateMobile")
	@Operation(summary = "修改登录手机号" , description = "修改登录手机号")
	public ServerResponseEntity<Void> updateMobile(@Valid @RequestBody UpdateMobileParam updateMobileParam) {
		if(StringUtil.isBlank(updateMobileParam.getMobile())){
			throw new YamiShopBindException("手机号码不能为空");
		}

		if(StringUtil.isBlank(updateMobileParam.getVerificationCode())){
			throw new YamiShopBindException("验证码不能为空");
		}

		String userId = SecurityUtils.getUser().getUserId();

		User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUserId, userId));
		if (user == null) {
			// 无法获取用户信息
			throw new YamiShopBindException("无法获取用户信息");
		}

		// 正在进行申请注册
		if (userService.count(new LambdaQueryWrapper<User>().eq(User::getUserMobile, updateMobileParam.getMobile())) > 0) {
			// 该用户名已注册，无法重新注册
			throw new YamiShopBindException("该手机号已存在,不能重复使用");
		}


		//缓存的验证码
		String redisCode = (String) RedisUtil.get(updateMobileCode + updateMobileParam.getMobile());

		if(StringUtils.isBlank(redisCode)){
			throw new YamiShopBindException("验证码已失效,请重新发送");
		}

		if(!StringUtils.equals(updateMobileParam.getVerificationCode(),redisCode)){
			throw new YamiShopBindException("验证码不正确");
		}


		User user1=new User();
		user1.setUserId(user.getUserId());
		user1.setModifyTime(new Date());
		user1.setUserMobile(updateMobileParam.getMobile());
		userService.updateById(user1);
		return ServerResponseEntity.success();
	}


	@PostMapping("/sendUpdateMobileCode")
	@Operation(summary = "发送修改手机号码验证码" , description = "发送修改手机号码验证码")
	public ServerResponseEntity<String> sendRegisterCode(String mobile) {
		if (!PrincipalUtil.isMobile(mobile)) {
			return ServerResponseEntity.showFailMsg("手机号码格式不正确");
		}
		//随机四位数
		String s =  RandomUtil.randomNumbers(4);

		String msg="";

		//发送验证码短信
		boolean prod = StringUtil.equals(springConfig.activeProfiles, "prod");
		if(prod){
			Map<String,String> map=new HashMap<>();
			map.put("code",s);
			sendSmsService.sendSms(mobile,"SMS_472795010",map);
			msg = "短信已发送";
		}else{
			msg = s;
		}

		//缓存验证码,三分钟失效
		RedisUtil.set(updateMobileCode+mobile,s,5*60);
		return ServerResponseEntity.success(msg);
	}

	@PostMapping("/setUserWxOpenId")
	@Operation(summary = "设置用户OpenId" , description = "设置用户OpenId")
	public ServerResponseEntity<Void> setUserWxOpenId(@RequestBody SetUserWxOpenIdParam setUserWxOpenIdParam) {
		String userId = SecurityUtils.getUser().getUserId();

		String openId = weChatPayment.getOpenId(setUserWxOpenIdParam.getCode());

		User user = new User();
		user.setUserId(userId);
		user.setWxOpenId(openId);
		userService.updateById(user);
		return ServerResponseEntity.success();
	}

	/**
	 * 获取下级用户,展示树形图(三级分销功能接口)
	 */
	@GetMapping("/getLowerLevel")
	public ServerResponseEntity<Map<String,Object>> getLowerLevel() {
		String userId = SecurityUtils.getUser().getUserId();
		List<UserTreeDto> lsit1=new ArrayList<>();
		List<User> lsit0=new ArrayList<>();

		//根用户
		User user = userService.getById(userId);
		lsit0.add(user);

		//下1级
		List<User> list = userService.lambdaQuery().eq(User::getHigherLevelUid, user.getUserId()).list();
		lsit0.addAll(list);

		//下2级
		List<String> collect = list.stream().map(u -> u.getUserId()).collect(Collectors.toList());
		if(collect.isEmpty()){
			collect.add("-1");
		}
		List<User> list1 = userService.lambdaQuery().in(User::getHigherLevelUid, collect).list();
		lsit0.addAll(list1);

		//下3级
		/*List<String> collect1 = list1.stream().map(u -> u.getUserId()).collect(Collectors.toList());
		if(collect1.isEmpty()){
			collect1.add("-1");
		}
		List<User> list2 = userService.lambdaQuery().in(User::getHigherLevelUid, collect1).list();
		lsit0.addAll(list2);*/


		for(User user1:lsit0){
			String vipLevelName=null;
			if (user1.getVipLevel() != null){
				if(user1.getVipLevel() == 0){
					vipLevelName = "普通会员";
				}else if(user1.getVipLevel() == 1){
					vipLevelName = "vip";
				}else if(user1.getVipLevel() == 2){
					vipLevelName = "svip";
				}else if(user1.getVipLevel() == 3){
					vipLevelName = "分部";
				}
			}

			UserTreeDto dto=new UserTreeDto();
			dto.setId(user1.getUserId());
			dto.setPid(user1.getHigherLevelUid());
			dto.setName(user1.getNickName()+(vipLevelName!=null?"("+vipLevelName+")":""));
			dto.setImage_url(user1.getPic());

			lsit1.add(dto);
		}

		Map<String, List<UserTreeDto>> collect2 = lsit1.stream().filter((m) -> !StringUtil.equals(m.getId(), user.getUserId())).collect(Collectors.groupingBy(m -> m.getPid()));
		lsit1.forEach(m -> m.setChildren(collect2.get(m.getId())));


		List<UserTreeDto> collect3 = lsit1.stream().filter((m) -> StringUtil.equals(m.getId(), user.getUserId())).collect(Collectors.toList());


		//查询当前用户推荐人
		Map<String,String> tjrmap=new HashMap<>();
		User higherLevelUser = userService.getById(user.getHigherLevelUid());
		if(higherLevelUser != null){
			tjrmap.put("uid",higherLevelUser.getHigherLevelUid());
			tjrmap.put("nickName",higherLevelUser.getNickName());
			tjrmap.put("realName",higherLevelUser.getRealName());
		}

		Map<String,Object> rmap=new HashMap<>();
		rmap.put("higherLevelUser",tjrmap);
		rmap.put("lowerLevelUser",collect3);

		return ServerResponseEntity.success(rmap);
	}

	/**
	 * 查看用户订单信息(三级分销功能接口)
	 * @param orderParam
	 * @param page
	 * @return
	 */
	@GetMapping("/getUserOrderInfo")
	public ServerResponseEntity<IPage<Order>> getUserOrderInfo(OrderParamPublicParam orderParam, PageParam<Order> page) {
		if(StringUtil.isBlank(orderParam.getUserId())){
			return ServerResponseEntity.showFailMsg("参数 userId 不能为空");
		}
		Long shopId = SecurityUtils.getUser().getShopId();
		orderParam.setShopId(shopId);
		IPage<Order> orderPage = orderService.pageOrdersDetailByOrderPublicParam(page, orderParam);
		return ServerResponseEntity.success(orderPage);
	}

	/**
	 * 获取指定订单奖励信息(三级分销功能接口)
	 * @param orderNumber
	 * @return
	 */
	@GetMapping("/getUserOrderBonusInfo")
	public ServerResponseEntity<List<UserFundDetailVo>> getUserOrderBonusInfo(String orderNumber) {
		if(StringUtil.isBlank(orderNumber)){
			return ServerResponseEntity.showFailMsg("参数 orderNumber 不能为空");
		}
		List<String> strings = Arrays.asList(UserFundDetailEnum.TYPE_0.getValue(), UserFundDetailEnum.TYPE_1.getValue(), UserFundDetailEnum.TYPE_2.getValue(), UserFundDetailEnum.TYPE_5.getValue());
		List<UserFundDetail> list1 = userFundDetailService.lambdaQuery()
				.eq(UserFundDetail::getCategory, UserFundDetailEnum.DISTRIBUTION_BONUS.getValue())
				.in(UserFundDetail::getType, strings)
				.eq(UserFundDetail::getOrderNumber, orderNumber)
				.list();
		List<UserFundDetailVo> volist=new ArrayList<>();
		for(UserFundDetail fundDetail:list1){
			UserFundDetailVo vo=new UserFundDetailVo();
			BeanUtil.copyProperties(fundDetail,vo);

			User byId = userService.getById(fundDetail.getUid());
			if (byId != null){
				vo.setUserName(byId.getNickName());
			}
			volist.add(vo);
		}

		return ServerResponseEntity.success(volist);
	}

	/**
	 * 查询当前登录用户的一级推荐人的数量(一级分销功能接口)
	 * @return
	 */
	@GetMapping("/getLevel1SharedPeopleNumber")
	public ServerResponseEntity<Map<String,Object>> getLevel1SharedPeopleNumber() {
		String userId = SecurityUtils.getUser().getUserId();
		//查看直推人数
		Long count = userService.lambdaQuery().eq(User::getSharedUid, userId).count();

		//查看以下所有推荐人
		List<User>  list0=userService.getLowerLevelBySharedUid(userId,new ArrayList<>());

		Map<String,Object> rmap=new HashMap<>();
		rmap.put("directPushNumber",count);
		rmap.put("lowerLevelNumber",list0.size());

		return ServerResponseEntity.success(rmap);
	}

	/**
	 * 普通会员升级为团长(一级分销功能接口)
	 * @return
	 */
	@PostMapping("/upgrade")
	public ServerResponseEntity<Boolean> upgrade(String teamName) {
		String userId = SecurityUtils.getUser().getUserId();
		if(StringUtil.isBlank(teamName)){
			return ServerResponseEntity.showFailMsg("参数 teamName 不能为空");
		}

		Integer directPushNumber0=null;
		Integer lowerLevelNumber0=null;

		//直推数量
		String directPushNumber = oneLevelDistributionService.getValueByConfig("upgrade_leader_direct_push_number");
		if(StringUtil.isBlank(directPushNumber)){
			return ServerResponseEntity.showFailMsg("参数 upgrade_leader_direct_push_number 未设置");
		}
		directPushNumber0 = Integer.valueOf(directPushNumber);

		//所有下级数量数量
		String lowerLevelNumber = oneLevelDistributionService.getValueByConfig("upgrade_leader_lower_level_number");
		if(StringUtil.isBlank(lowerLevelNumber)){
			return ServerResponseEntity.showFailMsg("参数 upgrade_leader_lower_level_number 未设置");
		}
		lowerLevelNumber0 = Integer.valueOf(lowerLevelNumber);



		//查看直推人数
		Long count = userService.lambdaQuery().eq(User::getSharedUid, userId).count();
		//查看以下所有推荐人
		List<User>  list0=userService.getLowerLevelBySharedUid(userId,new ArrayList<>());

		if(!(count >= directPushNumber0 || list0.size() >= lowerLevelNumber0)){
			return ServerResponseEntity.showFailMsg("直推用户数量不超过:"+directPushNumber0+",下级用户数量不超过:"+lowerLevelNumber0+" 不能升级团长");
		}

		Long count1 = userService.lambdaQuery().eq(User::getTeamName, teamName).count();
		if(count1 > 0){
			return ServerResponseEntity.showFailMsg("参数 teamName 已被占用,请更换后重试");
		}

		User user=new User();
		user.setUserId(userId);
		user.setSharedUid("");//升级后再最顶级,无推荐人
		user.setUserLevel(1);//团长
		user.setTeamName(teamName);

		userService.updateById(user);

		//设置为NULL
		userService.lambdaUpdate()
				.set(User::getSharedUid,null)
				.set(User::getUserLevelExpireDate,null)//升级为团长后,不会自动超时
				.eq(User::getUserId,userId).update();

		return ServerResponseEntity.success(true);
	}

	/**
	 * 获取配置项
	 * @param key
	 * @return
	 */
	@GetMapping("/getConfigByKey")
	public ServerResponseEntity<String> getConfigByKey(String key) {
		String lowerLevelNumber = oneLevelDistributionService.getValueByConfig(key);
		return  ServerResponseEntity.success(lowerLevelNumber);
	}
}
